/**
 *  枚举类型
 *  1.rust枚举类型相当之怪异 
 *  2.枚举的定义中，允许实例包含数据，也可以不包含数据。
 *  3.当枚举类型中包含数据时，不同的枚举实例还可以包含不同的类型的数据。
 *  4.枚举的成员只能包含（a-z, A-Z）、数字（0-9）、下划线（_）以及 Unicode 非字母数字字符
 *    不能以数字开头
 * 
 *  当每个枚举成员都可以不同的时候，我们把它理解成java的Object类型即可。
 *  总之，rust的枚举类型极其怪，不同于于其它语言。个人认为这种怪异并没有存在的必要。
 *   
 *  枚举的定义中，枚举成员的命名方式为：首字母大写。  
 *  
 */

//a.最简单的枚举，不含数据
#[derive(Debug)]
enum simple_enum {
    Man,
    Women,
    Other
}

//b. 枚举类型中包含数据
#[derive(Debug)]
enum color {
    Red,
    Green = 3
}

//c.枚举类型中包含多个数据,且都是一样的
#[derive(Debug)]
#[derive(PartialEq)]
enum grade {
    A(u32,String),
    B(u32,String),
    C(u32,String)
}

//枚举的方法，定义上了struct方法类似，都是impl,&self
impl grade {
    fn print(&self) {   
        //这个tmd也太麻烦了吧
        match self {
            grade::A(a,b) => println!("{}-{}",a,b),
            grade::B(a,b) => println!("{}-{}",a,b),
            grade::C(a,b) => println!("{}-{}",a,b)
        }
    }
}


#[derive(Debug)]
enum food<'a>{
    蔬菜([String;5]),
    禽肉,
    猪肉,
    牛羊肉,
    海鲜,
    大米,
    水果(&'a str,&'a str,&'a str)
}

fn main() {
    let a = simple_enum::Man;
    println!("{:?}",a);
    // 使用println! :?宏打印枚举的时候，变量名称不能同枚举成员。否则会报错
    let gr = color::Green;  
    println!("{:?}",gr);
    let r = color::Red;
    println!("{:?}",r);

    let grade_a = grade::A(10,String::from("差"));
    let grade_a1=grade::A(9,String::from("差011"));
    grade_a.print();
    println!("{:?}",grade_a);
    if (grade_a == grade_a1){
        println!("相等");
    }
    else{
        println!("不相等");
    }

    let fruit= food::水果("苹果","香蕉","梨子");
    println!("{:?}",fruit);
    print_first_fruit_member(fruit);
    let v = food::蔬菜(["白菜".to_string(),"萝卜".to_string(),"黄瓜".to_string(),"冬瓜".to_string(),"南瓜".to_string()]);
    println!("{:?}",v);
}

fn print_first_fruit_member<'a>(fruit: food<'a>) {
    if let food::水果(first, second, third) = fruit {
        println!("{},{},{}", first,second,third);
    } else {
        println!("The provided food is not a fruit.");
    }
}